package code.framework.android.view;

import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import code.framework.android.core.ApplicationContextHelper;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public abstract class ApplicationViewManager {

	protected static final String CONTAINER = "container";

	protected Class<?> resourceLayoutClass;
	protected Class<?> resourceIdClass;
	protected LayoutInflater layoutInflator;

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	protected ApplicationViewManager() {
		this.setResourceLayoutClass();
		this.setResourceIdClass();
	}

	protected LayoutInflater getLayoutInflater(Context context) {
		if (layoutInflator == null) {
			layoutInflator = ApplicationContextHelper
					.getLayoutInflater(context);
		}
		return layoutInflator;
	}

	public void setContentView(Activity activity, String layoutId) {
		try {
			final Field resField = resourceLayoutClass.getField(layoutId);
			final Integer resId = resField.getInt(resourceIdClass);
			activity.setContentView(resId);
			logger.trace("setContentView: {}", resId);
		} catch (Exception e) {
			// suppress
			logger.error("", e);
		}
	}

	public void reflect(Activity activity, ViewHolder holder) {
		logger.debug("reflect()");
		final Field[] fs = holder.getClass().getDeclaredFields();
		for (Field f : fs) {
			try {
				final Field resField = resourceIdClass.getField(f.getName());
				logger.trace("resField = {}", resField);
				final Integer resId = resField.getInt(resourceIdClass);
				logger.trace("resId = {}", resId);
				final View view = activity.findViewById(resId);
				logger.trace("view = {}", view);
				f.set(holder, view);
				logger.trace("reflect: {}", view);
			} catch (Exception e) {
				// suppress
				logger.error("", e);
			}
		}
	}

	/**
	 * By reflections, reference the holder to the views from group
	 * 
	 * Weird type of reflections
	 * 
	 * @param viewGroup
	 * @param holder
	 */
	public void reflect(ViewGroup viewGroup, ViewHolder holder) {
		logger.debug("reflect()");
		final Field[] fs = holder.getClass().getDeclaredFields();
		for (Field f : fs) {
			if (!CONTAINER.equals(f.getName())) {
				try {
					final Field resField = resourceIdClass
							.getField(f.getName());
					final Integer resId = resField.getInt(resourceIdClass);
					final View view = viewGroup.findViewById(resId);
					f.set(holder, view);
					logger.trace("reflect: {}", view);
				} catch (Exception e) {
					// suppress
					logger.error("", e);
				}
			}
		}
	}

	protected abstract void setResourceIdClass();

	protected abstract void setResourceLayoutClass();

}
